﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HandyControl.Controls;
using MyHelper;
using Brushes = System.Windows.Media.Brushes;
using ContextMenu = System.Windows.Controls.ContextMenu;
using Cursors = System.Windows.Input.Cursors;
using Log = MyHelper.Log;
using UserControl = System.Windows.Controls.UserControl;

namespace weighing
{
    /// <summary>
    /// VideoContent.xaml 的交互逻辑
    /// </summary>
    public partial class VideoContent : UserControl
    {
        #region variables
        /// <summary>
        /// 数据库存中保存的摄像头信息
        /// </summary>
        public List<CameraInfoVo>? mCameraInfoVos = new();

        private List<CHCNetSDK.NET_DVR_DEVICEINFO_V40>? mDeviceInfors = new();

        #endregion

        public VideoContent()
        {
            InitializeComponent();
            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) return;

            this.SizeChanged += VideoContent_SizeChanged;
            this.IsVisibleChanged += VideoContent_IsVisibleChanged;
        }


        private void VideoContent_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (this.IsLoaded == false) return;

        }

        private void Video_Connet_Loaded(object sender, RoutedEventArgs e)
        {
            if (IsVisible)
            {
                ShowCamera();
            }
        }

        private void VideoContent_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (IsVisible && this.IsLoaded)
            {
                ShowCamera();
            }
        }
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int loginDelete([MarshalAs(UnmanagedType.LPWStr)] CameraInfoVo vo);

        private void ShowCamera()
        {
            if (!App.Config.UserConfig.ShowVideoArea) return;

            if (mCameraInfoVos == null || mCameraInfoVos.Count <= 0)
            {
                var list = CameraInfoDao.Instance.GetShowList();
                mCameraInfoVos = list?.Select((i) => { return new CameraInfoVo(i); }).ToList();

                if(mCameraInfoVos.IsNullOrEmpty()) return;
            }
            else
            {
                //第二次加载
                StorpPreviewCamera();
                LogoutCamera();
            }
            if (mCameraInfoVos.Count <= 0)
            {
                string msg = "视频显示失败，没有添加任何摄像头";               
                Log.WriteLine(msg);
                return;
            }
            this.CameraPanel.Children.Clear();
            this.CameraPanel.Rows = 1;
            if (mCameraInfoVos.Count <= 3)
            {
                this.CameraPanel.Columns = mCameraInfoVos.Count;
            }
            mDeviceInfors = new List<CHCNetSDK.NET_DVR_DEVICEINFO_V40>();
            this.Cursor = Cursors.Wait;
            //设置视频的布局
            int videoCunt = mCameraInfoVos.Count;
            if (videoCunt > 3)
            {
                if (videoCunt == 4)
                {
                    CameraPanel.Columns = 4;
                }
                else
                {
                    CameraPanel.Rows = videoCunt % 3 > 0 ? (videoCunt / 3) + 1 : (videoCunt / 3);
                }
            }

            for (int i = 0; i < mCameraInfoVos.Count; i++)
            {
                CameraInfoVo camera = mCameraInfoVos[i];               
                    if (!camera.SdkHepler.InitSDK())
                    {
                        string msg = "摄像头SDK初始化失败!";
                        Growl.InfoGlobal(msg);
                        return;
                    }              
                try
                {
                    int loginHandle = camera.Login();
                    if (loginHandle < 0)
                    {
                        TextBlock textBlock = new TextBlock
                        {
                            TextAlignment = TextAlignment.Center,
                            HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                            VerticalAlignment = VerticalAlignment.Center,
                            Text = "登陆失败",
                            FontSize = 16,
                            Foreground = Brushes.Red,
                            ToolTip = camera.Ip + ":" + camera.Port,
                            ContextMenu = FindResource("ReFreshContextMenu") as ContextMenu                           
                        };
                        CameraPanel.Children.Add(textBlock);
                        continue;
                    }
                    WindowsFormsHost formsHost = new WindowsFormsHost() { Margin = new Thickness(2), };
                    PictureBox pictureBox = new PictureBox
                    {
                        Name = $"picture{i}",
                        Margin = new Padding(0, 0, 0, 2),
                        Height = (int)this.ActualHeight,
                        Tag = camera,
                    };
                    pictureBox.MouseDoubleClick += PictureBox_MouseDoubleClick;
                    pictureBox.SendToBack();
                    camera.PictureHandle = pictureBox.Handle;
                    camera.PreView(out uint errroCode);
                    if (camera.PreviewHandle < 0)
                    {
                        TextBlock tb = new TextBlock
                        {
                            VerticalAlignment = VerticalAlignment.Center,
                            HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                            FontSize = 14,
                            Foreground = Brushes.DarkGray,
                            Text = "视频播放错误：" + errroCode,
                            ToolTip = camera.Ip + ":" + camera.Port
                        };
                        CameraPanel.Children.Add(tb);
                    }
                    else
                    {
                        //成功                       
                        formsHost.Child = pictureBox;
                        CameraPanel.Children.Add(formsHost);
                    }
                }
                catch (Exception e)
                {
                    TextBlock textBlock = new TextBlock
                    {
                        TextAlignment = TextAlignment.Center,
                        HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                        VerticalAlignment = VerticalAlignment.Center,
                        Text = "异常: " + e.Message,
                        FontSize = 16,
                        Foreground = Brushes.Red,
                        ToolTip = camera.Ip + ":" + camera.Port
                    };
                    CameraPanel.Children.Add(textBlock);
                }
            }
            this.Cursor = Cursors.Arrow;
        }

        /// <summary>
        /// 双击查看大图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void PictureBox_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            PictureBox pictureBox = sender as PictureBox;
            CameraInfoVo camera = pictureBox.Tag as  CameraInfoVo;
            if(camera != null)
            {
                new BigVideoWindow(camera).ShowDialog();
            }
        }

        /// <summary>
        /// 当摄像头改时
        /// </summary>
        /// <param name="cameraVo"></param>
        public void OnCameraChanged(CameraInfoVo cameraVo)
        {
            if(App.Config.UserConfig.ShowVideoArea == false)
            {
                //没有开启视频显示
                return;
            }
            if (cameraVo == null) return;
            int index = -1;
            for (int i = 0;i<mCameraInfoVos.Count;i++)
            {
                if (mCameraInfoVos[i].Id == cameraVo.Id)
                {                 
                    index = i;
                    break;
                }
            }
            if (index == -1)
            {
                mCameraInfoVos.Add(cameraVo);
            }
            else
            {
                if(cameraVo .IsPlay ==1)
                {
                    mCameraInfoVos[index] = cameraVo;                   
                }
                else
                {
                    //不显示
                    mCameraInfoVos.RemoveAt(index);
                }               
            }
            //重先加载
            ShowCamera();
        }

        public void StorpPreviewCamera()
        {
            try
            {
                mCameraInfoVos?.ForEach((vo) => { vo.SdkHepler.StopPreview(vo.PreviewHandle); });
            }
            catch (Exception e)
            {
                ConsoleHelper.writeLine("停止预览失败: " + e.Message);
            }
        }

        public void PreviewCamera()
        {
            try
            {
                mCameraInfoVos?.ForEach((vo => { vo.SdkHepler.Preview(vo.PictureHandle, vo.LoginHandle, vo.ChanNum, out uint errcode); }));
            }
            catch (Exception e)
            {
                ConsoleHelper.writeLine("停止预览失败: " + e.Message);
            }
        }
        private void LogoutCamera()
        {
            mCameraInfoVos?.ForEach(item => { item.SdkHepler.LoginOut(item.LoginHandle); });
        }

        /// <summary>
        /// 通道截图，没有过磅数据或者没有视频，不可以截图
        /// </summary>
        public void CaptureJpeg(string number, int status)
        {
            if (mCameraInfoVos.Count <= 0)
            {
                string msg = "没有视频，不可以截图";
                Growl.Info(msg, "main");
                return;
            }

            if (WeighingBillDao.Instance.FindByNumber(number) == null)
            {
                string msg = "没有过磅数据，不可以截图";
                Growl.Info(msg, "main");
                return;
            }

            string bilNumber = number;
            string statusTag =status == 1 ? "out" : "in";
            string filePath = UrlHelper.Decode(App.Config.ImgConfig.CapturePath);
            if (!(filePath.Contains("\\") || filePath.Contains("\\\\")))
            {
                filePath = UrlHelper.Decode(App.Config.ImgConfig.CapturePath);
            }

            string d = DateTime.Now.Date.ToString("yyyy-MM-dd");
            if (String.IsNullOrEmpty(filePath))
            {
                filePath = System.IO.Path.Combine(FileHelper.GetRunTimeRootPath(), "capture");
            }
            filePath = System.IO.Path.Combine(filePath, d);
            if (!FileHelper.FolderExistsCreater(filePath))
            {
                string msg = bilNumber + " 保存截图的路径不存在 ，不能截图";
                Log.Error(msg);
                return;
            }
            String fileName = String.Empty;
            //根据登录成功的通过截图
            for (int i = 0; i < mCameraInfoVos.Count; i++)
            {
                try
                {
                    CameraInfoVo vo = mCameraInfoVos[i];
                    if(vo.IsCapture == 0) continue;
                    if (string.IsNullOrEmpty(bilNumber))
                    {
                        fileName = Guid.NewGuid() + Constant.CaputureSuffix;
                    }
                    else
                    {
                        fileName = bilNumber + "_" + statusTag + i + Constant.CaputureSuffix;
                    }

                   
                    String fileNamePath = System.IO.Path.Combine(filePath, fileName);

                    bool res = vo.CaptureJpeg(fileNamePath);

                    if (res == true)
                    {
                        string positionName = (vo == null || vo.PositionName.IsNullOrEmpty()) ? "视频截图" : vo.PositionName;
                        this.Dispatcher.Invoke(() =>
                        {
                            BillImageDao.Instance.SaveCuptureImage(number, fileNamePath, (int)CamaraPosition.Foreground, positionName);
                        });
                        //截图压缩 
                        try
                        {
                            FileInfo info = new FileInfo(fileNamePath);
                            if (info.Exists && info.Length > Constant.ImageCompresLength)
                                ImageHelper.CompresOvrite(fileNamePath);
                        }
                        catch (Exception ex)
                        {
                           Log.Error("截图压缩失败：" + ex.Message + " 图片：" + fileNamePath);
                        }
                    }
                    else
                    {
                      Log.Error($"{number} 截图失败！");
                    }
                }
                catch (Exception ex)
                {

                    Log.Error($"{number} 截图失败:" + " \r\n" +ex.Message+ " \r\n" + ex.StackTrace);
                }
               
            }
        }

        private void Video_Connet_Unloaded(object sender, RoutedEventArgs e)
        {
            StorpPreviewCamera();
            LogoutCamera();
        }

        public void ReFresh_MI_Click(object sender, RoutedEventArgs e)
        {
            StorpPreviewCamera();
            LogoutCamera();
            ShowCamera();
        }
    }
}
